﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace CommonClasses.Utility
{
    /// <summary>
    /// Утилитный класс для работы со строками
    /// </summary>
    public static class StringUtility
    {
        /// <summary>
        /// Конертация координат символа в индекс в строке
        /// </summary>
        /// <param name="source">исходная строка</param>
        /// <param name="_coordiantes">координаты: X - номер символа в строке, Y - номер строки</param>
        /// <returns>индекс</returns>
        public static int CoordinatesToIndex(string source, Point _coordinates)
        {
            int index = 0, lineCount = 0;
            while ((index < source.Length) && (lineCount != _coordinates.Y))
            {
                if (source[index] == '\n') lineCount++;
                index++;
            }

            index += _coordinates.X;

            if (index >= source.Length) throw new IndexOutOfRangeException("Char coordinates are wrong or incompatible string format!");

            return index;
        }

        /// <summary>
        /// Вставляет в строку source строку sample во все точки, заданные координатами _coordinates
        /// </summary>
        /// <param name="source">исходная строка</param>
        /// <param name="samples">строки-образцы для вставки</param>
        /// <param name="_coordiantes">координаты: X - номер символа в строке, Y - номер строки</param>
        /// <returns>новая строка со вставленными подстроками</returns>
        public static string Inline(string source, IDictionary<string, Point> samples)
        {
            StringBuilder str = new StringBuilder(source);
            foreach (var pair in samples)
                str.Insert(CoordinatesToIndex(source, pair.Value), pair.Key);                
            return str.ToString();
        }

        /// <summary>
        /// Преобразовать линейный индекс в данной строке в координаты.
        /// <remarks>
        /// Y - номер строки, нумерация строк начинается с 1.
        /// X - номер символа в строке.
        /// </remarks>
        /// </summary>
        /// <param name="source">
        /// Строка, по которой будет происходить преобразование
        /// </param>
        /// <param name="index">
        /// Линейный индекс (номер символа) в строке.
        /// </param>
        /// <returns>
        /// Координаты, соответствующие указанному линейному индексу
        /// </returns>
        public static Point IndexToCoordinates(this string source, int index)
        {
            var result = new Point(0, 1);

            for (int i = 0; i < Math.Min(index, source.Length); i++)
                if (source[i] == '\n')
                {
                    result.Y++;
                    result.X = 0;
                }
                else
                    result.X++;

            return result;
        }
    }
}
